home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
tools
/
zmc3v078
/
zmc3v078.lzh
/
SRCSV078.LZH
/
BRACKET.C
< prev
next >
Wrap
C/C++ Source or Header
|
2000-06-01
|
49KB
|
1,880 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "etc.h"
#include "makezmd1.h"
#include "makezmd2.h"
#include "makezmd3.h"
#include "parsesub.h"
#include "velo.h"
#include "68lib.h"
#include "arcc.h"
#include "portamnt.h"
#include "structs.h"
#include "structs2.h"
UBYTE *makeZmdCommand(UBYTE *zms,TRKCHINF *trkdata, BYTE target[],
TRKINF *trkinf,COMMONINF *cominf);
UBYTE *makeCHfader(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[],
TRKINF *trkinf, COMMONINF *cominf, int trk_fader);
UBYTE *makeZmdEffect(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[]);
UBYTE *makeZmdEffect2(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[],
const BYTE mode);
UBYTE *makeZmdInstrumentId(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[]);
UBYTE *makeZmdSynchronize(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[],
COMMONINF *cominf);
UBYTE *makeZmdBar(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[]);
UBYTE *makeZmdTieMode(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[]);
UBYTE *makeZmdTrackMode(UBYTE *zms, TRKCHINF *trkdata, TRKINF *trkinf,
const BYTE target[]);
UBYTE *makeZmdTrackDelay(UBYTE *zms_, TRKCHINF *trkdata, const BYTE target[],
TRKINF *trkinf, COMMONINF *cominf, int mode);
void makeZmdAllSoundOff(TRKCHINF *trkdata, const BYTE target[]);
UBYTE *makeZmdEcho(UBYTE *zms, TRKCHINF *trkdata, TRKINF *trkinf,
const BYTE target[], COMMONINF *cominf);
UBYTE *makeZmdDamper(UBYTE *zms, TRKCHINF *trkdata,
const BYTE target[], int mode);
UBYTE *makeZmdBendRange(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[]);
UBYTE *makeZmdProgramChange(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[]);
UBYTE *makeZmdProgramBankChange(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[]);
UBYTE *makeZmdSetNRPN(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[]);
UBYTE *makeZmdKsign(UBYTE *zms, const BYTE target[],TRKINF *trkinf);
UBYTE *makeZmdReplay(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[]);
void makeZmdDummy(TRKCHINF *trkdata, const BYTE target[]);
UBYTE *makeZmdComment(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[]);
UBYTE *makeZmdEvent(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[]);
UBYTE *makeZmdPanpot(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[], int mode);
UBYTE *makeZmdTempo(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[], int mode);
UBYTE *makeZmdVolume(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[],
TRKINF *trkinf, int mode);
UBYTE *makeZmdExclusive(UBYTE *zms,TRKCHINF *trkdata,
const BYTE target[], UBYTE mode);
void makeZmdPitch(TRKCHINF *trkdata, int Trk, int st, DWORD var);
UBYTE *makeZmdBend(UBYTE *zms, TRKCHINF *trkdata, TRKINF *trkinf, const BYTE target[], int st);
UBYTE *makeZmdProgramSplit(UBYTE *zms, TRKCHINF *trkdata, TRKINF *trkinf, const BYTE target[]);
UBYTE *getZmsNoteSub(UBYTE *zms, TRKINF *trkinf, const int Trk, BYTE *note);
extern DWORD line;
extern char *linebuf;
extern LINEDATA *ld;
enum {
#define ZMSCOMMAND(c,s) c,
#include "trkcmd.h"
#include "zmscmd.h"
#undef ZMSCOMMAND
dummy /* it's needed for BCB */
};
UBYTE *makeZmdCommand(UBYTE *zms,TRKCHINF *trkdata, BYTE target[],
TRKINF *trkinf,COMMONINF *cominf)
{ /* |: |n | */
int trk,i;
UBYTE *zms_ = zms;
/* DWORD line_ = line; */
const struct {
int zmscmdcode;
char *zmscmd;
} comtbl1[] = {
#define ZMSCOMMAND(c,s) {c, s},
#include "trkcmd.h"
#include "zmscmd.h"
#undef ZMSCOMMAND
{-1, NULL},
};
for (i = 0;;i++) {
if (!comtbl1[i].zmscmd) break;
if (!stricmp2(zms,comtbl1[i].zmscmd)) {
zms += strlen(comtbl1[i].zmscmd);
break;
}
}
i = comtbl1[i].zmscmdcode;
switch (i) {
case ZMSCMD_DC: /* [d.c.] */
/*OK*/ for (trk = 0; target[trk] >= 0; trk++) {
*trkdata[target[trk]].zmd++ = 0xC5;
*trkdata[target[trk]].zmd++ = 0x00;
}
break;
case ZMSCMD_SEGNO: /* [segno] */
case ZMSCMD_DOLLAR: /* [$] */
/*OK*/ for (trk = 0; target[trk] >= 0; trk++) {
int Trk = target[trk];
do {
*trkdata[Trk].zmd++ = 0xD0;
if (!trkinf[Trk].segno) {
trkinf[Trk].segno = trkdata[Trk].zmd - trkdata[Trk].zmdbuf;
}
putDword(trkdata[Trk].zmd, 0);
trkdata[Trk].zmd += 4;
} while (trkinf[Trk].back_repeat && (Trk = cominf->backtrk[Trk]) != -1);
}
break;
case ZMSCMD_DS: /* [d.s.] */
/*OK*/ for (trk = 0; target[trk] >= 0; trk++) {
int Trk = target[trk];
do {
if (!trkinf[Trk].segno) {
zmserror("[d.s.] command must comes after [segno] or [$].",line,linebuf,zms_,0,1);
}
*trkdata[Trk].zmd++ = 0xD3;
putDword(trkdata[Trk].zmdbuf + trkinf[Trk].segno,
trkdata[Trk].zmd - trkdata[Trk].zmdbuf - trkinf[Trk].segno - 4);
*trkdata[Trk].zmd++ = 0x00;
putDword(trkdata[Trk].zmd,
trkinf[Trk].segno - (trkdata[Trk].zmd - trkdata[Trk].zmdbuf));
trkdata[Trk].zmd += 4;
trkinf[Trk].segno = 0;
} while (trkinf[Trk].back_repeat && (Trk = cominf->backtrk[Trk]) != -1);
}
break;
case ZMSCMD_CODA: /* [coda] */
/*OK*/ for (trk = 0; target[trk] >= 0; trk++) {
int Trk = target[trk];
do {
if (!trkinf[Trk].coda) {
zmserror("[coda] command must comes after [tocoda] or [$].",line,linebuf,zms_,0,1);
}
*trkdata[Trk].zmd++ = 0xD1;
putDword(trkdata[Trk].zmd,
trkinf[Trk].coda - (trkdata[Trk].zmd - trkdata[Trk].zmdbuf) - 4);
putDword(trkdata[Trk].zmdbuf + trkinf[Trk].coda + 1,
trkdata[Trk].zmd - trkdata[Trk].zmdbuf - trkinf[Trk].coda - 1);
trkdata[Trk].zmd += 4;
trkinf[Trk].coda = 0;
} while (trkinf[Trk].back_repeat && (Trk = cominf->backtrk[Trk]) != -1);
}
break;
case ZMSCMD_TOCODA: /* [tocoda] */
case ZMSCMD_ASTARISK: /* [*] */
/*OK?*/ for (trk = 0; target[trk] >= 0; trk++) {
int Trk = target[trk];
do {
*trkdata[Trk].zmd++ = 0xD4;
if (!trkinf[Trk].coda) {
trkinf[Trk].coda = trkdata[Trk].zmd - trkdata[Trk].zmdbuf;
}
*trkdata[Trk].zmd++ = 0x00;
putDword(trkdata[Trk].zmd, 0);
trkdata[Trk].zmd += 4;
} while (trkinf[Trk].back_repeat && (Trk = cominf->backtrk[Trk]) != -1);
}
break;
case ZMSCMD_FINE: /* [fine] */
case ZMSCMD_FINE2: /* [^] */
/*OK*/ for (trk = 0; target[trk] >= 0; trk++) {
int Trk = target[trk];
do {
*trkdata[Trk].zmd++ = 0xFC;
} while (trkinf[Trk].back_repeat && (Trk = cominf->backtrk[Trk]) != -1);
}
break;
case ZMSCMD_DO: /* [do] */
/*OK*/ for (trk = 0; target[trk] >= 0; trk++) {
int Trk = target[trk];
do {
recoverSpecialVelocity(trkinf, Trk);
trkinf[Trk].d->looptime = 1;
*trkdata[Trk].zmd++ = 0xC5;
*trkdata[Trk].zmd++ = 0x01;
*trkdata[Trk].zmd++ = 0x00;
} while (trkinf[Trk].back_repeat && (Trk = cominf->backtrk[Trk]) != -1);
}
break;
case ZMSCMD_LOOP: /* [loop] */
/*tenuki*/ for (trk = 0; target[trk] >= 0; trk++) {
int Trk = target[trk];
do {
trkinf[Trk].d->looptime = 0;
*trkdata[Trk].zmd++ = 0xF5;
putDword(trkdata[Trk].zmd, 0);
trkdata[Trk].zmd += 4;
} while (trkinf[Trk].back_repeat && (Trk = cominf->backtrk[Trk]) != -1);
}
break;
case ZMSCMD_DEBUG1: /* [!] */
/*OK*/ if (cominf->debug) {
for (trk = 0; target[trk] >= 0; trk++) {
int Trk = target[trk];
do {
*trkdata[Trk].zmd++ = 0xC5;
*trkdata[Trk].zmd++ = 0x02;
*trkdata[Trk].zmd++ = 0x00;
} while (trkinf[Trk].back_repeat && (Trk = cominf->backtrk[Trk]) != -1);
}
} else {
zmserror("debug command [!] is still existing.",line,linebuf,zms_,3,1);
}
break;
case ZMSCMD_DEBUG2: /* [@] */
/*OK*/ if (cominf->debug) {
for (trk = 0; target[trk] >= 0; trk++) {
int Trk = target[trk];
do {
*trkdata[Trk].zmd++ = 0xC5;
*trkdata[Trk].zmd++ = 0x03;
*trkdata[Trk].zmd++ = 0x02;
} while (trkinf[Trk].back_repeat && (Trk = cominf->backtrk[Trk]) != -1);
}
} else {
zmserror("debug command [@] is still existing.",line,linebuf,zms_,2,1);
}
break;
case ZMSCMD_END: /* [end] */
/*OK*/ for (trk = 0; target[trk] >= 0; trk++) {
int Trk = target[trk];
do {
*trkdata[Trk].zmd++ = 0xFF;
} while (trkinf[Trk].back_repeat && (Trk = cominf->backtrk[Trk]) != -1);
}
break;
case ZMSCMD_BACK: /* [back */
/*OK?*/ for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
DWORD backtrk, notfirsttime = 1;
if (!stricmp2(zms,".repeat")) { /* [back.repeat */
const char *p[] = {"off","on",NULL};
DWORD para;
int err;
zms = getnum4(zms + 7,¶,&err, p, 0);
if (err) {
zmserror("[back.repeat] needs a parameter.",line,linebuf,zms,0,1);
} else {
trkinf[Trk].back_repeat = para;
}
}
if (cominf->backtrk[Trk] < 0) { /* 1st time to use [back] in this trk */
int i;
for (i = 1; i < cominf->maxtrk; i++) {
if (trkdata[i].ch < 0) {
int trks;
char s[32];
sprintf(s,"trkdata[%d].zmdbuf_in_BACK",i);
cominf->backtrk[Trk] = backtrk = i;
cominf->fromtrk[i] = Trk;
cominf->backtrk[i] = -1;
cominf->backinuse = 1;
trkdata[i].zmdbuf = (UBYTE*)emalloc(sizeof(UBYTE) * 8192,s);
trkdata[i].bufsize = 8192;
trkdata[i].zmd = trkdata[i].zmdbuf;
trkdata[i].nowsize = 0;
trkdata[i].mute = 1;
initTrkInf(&trkinf[i], cominf);
for (trks = 0; trks < cominf->maxtrk; trks++) {
if (cominf->trkassign[trks] < 0) {
cominf->trkassign[trks] = backtrk;
cominf->trkassign[trks + 1] = -1;
break;
}
}
trkinf[i].l = (LOOPDATA*)NULL;
trkinf[i].d = (LOOPDATA*)NULL;
trkinf[i].r = (RENP*)NULL;
trkinf[i].s = (CHKSTEP*)NULL;
notfirsttime = 0;
break;
}
}
if (i >= cominf->maxtrk) {
zmserror("Sorry too many [back]. (however it will be modified soon)",line,linebuf,zms,0,1);
}
} else {
backtrk = cominf->backtrk[Trk];
if (trkinf[backtrk].total > trkinf[Trk].total) {
zmserror("Previous [back] sequence has not finished yet.",line,linebuf,zms,2,1);
}
}
if (notfirsttime && (trkinf[backtrk].total < trkinf[Trk].total)) {
DWORD d = trkinf[Trk].total - trkinf[backtrk].total;
*trkdata[backtrk].zmd++ = 0x80; /* 休符挿入(0.69) */
trkdata[backtrk].zmd += putZvar(trkdata[backtrk].zmd, d);
trkdata[backtrk].zmd += putZvar(trkdata[backtrk].zmd, d);
}
copyTrkInf(&trkinf[backtrk], &trkinf[Trk]); /* copy current track setting */
trkdata[backtrk].ch = trkdata[Trk].ch;
trkdata[backtrk].ch_ = trkdata[Trk].ch_;
trkdata[backtrk].chtype = trkdata[Trk].chtype;
trkdata[backtrk].trkv = trkdata[Trk].trkv;
trkdata[backtrk].trkf = trkdata[Trk].trkf;
trkdata[backtrk].trks = trkdata[Trk].trks;
trkdata[backtrk].trkm = trkdata[Trk].trkm;
trkdata[backtrk].cmnt = trkdata[Trk].cmnt; /* free時注意!! */
trkdata[backtrk].backinuse = -1;
*trkdata[backtrk].zmd++ = 0xFB; /* receiving sync. signal */
/* if (trkinf[backtrk].transpose != trkinf[Trk].transpose) { */
*trkdata[backtrk].zmd++ = 0xAB; /* send transpose info. */
*trkdata[backtrk].zmd++ = trkinf[Trk].transpose;
/* } */
for (i = 0; i < cominf->maxtrk; i++) { /* sending synchronous signal */
if (cominf->trkassign[i] == backtrk) {
*trkdata[Trk].zmd++ = 0xBE;
putWord(trkdata[Trk].zmd, i); /* - 1; */
trkdata[Trk].zmd += 2;
break;
}
}
if (i >= cominf->maxtrk) {
zmserror("illegal track number.",line,linebuf,zms,0,1);
}
/* trkinf[backtrk] = trkinf[Trk]; */ /* already copied in copyTrkInf() */
initTrkInf2(&trkinf[backtrk],backtrk); /* don't copy the informations
about {{..}}, |:..:|, & so on */
trkdata[Trk].backinuse = backtrk;
target[trk] = backtrk;
zmserror("[back] can use only for zmc2/zmc3.",line,linebuf,zms,4,1);
}
return zms; /* to avoid ']' check ... to be effective for [back.repeat] */
/* break; */
case ZMSCMD_TIMBRE: /* [timbre] */
case ZMSCMD_PROGRAM: /* [program] */
zms = makeZmdProgramChange(zms, trkdata, target);
break;
case ZMSCMD_TIMBRE_BANK: /* [timbre_bank] */
case ZMSCMD_PROGRAM_BANK: /* [program_bank] */
zms = makeZmdProgramBankChange(zms, trkdata, target);
break;
case ZMSCMD_TIMBRE_SPLIT: /* [timbre_split] */
case ZMSCMD_PROGRAM_SPLIT: /* [program_split] */
zms = makeZmdProgramSplit(zms, trkdata, trkinf, target);
break;
case ZMSCMD_BEND: /* [bend] */
zms = makeZmdBend(zms, trkdata, trkinf, target, 1);
break;
case ZMSCMD_BEND_SWITCH: /* [bend.switch] */
{
int trk, err;
DWORD para;
const char *p[] = {"off","on",NULL};
zms = getnum4(zms,¶,&err, p, 0);
if (!err) {
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
*trkdata[Trk].zmd++ = 0x98;
*trkdata[Trk].zmd++ = para;
}
} else {
zmserror("[BEND.SWITCH] require its parameter.",line,linebuf,zms,4,1);
}
}
break;
case ZMSCMD_BEND_RANGE: /* [bend_range] */
zms = makeZmdBendRange(zms, trkdata, target);
break;
case ZMSCMD_PITCH: /* [pitch] */
case ZMSCMD_ATPITCH: /* [@pitch] */
{
int trk, err;
DWORD var;
int st = (i == ZMSCMD_PITCH)? 1 : 3;
zms = getnum2(zms,&var,&err);
if (!err) {
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
makeZmdPitch(trkdata, Trk, st, var);
}
} else {
zmserror("[PITCH]/[@PITCH] require its parameter.",line,linebuf,zms,4,1);
}
}
break;
/* [push_portament] */
/* [pull_portament] */
/* [auto_portament] */
/* [auto_portament.switch] */
case ZMSCMD_AUTO_PORTAMENT: /* [auto_portament] */
zms = makeZmdAutoPortament(zms, trkdata, trkinf, target);
break;
case ZMSCMD_AUTO_PORTAMENT_SWITCH: /* [auto_portament.switch] */
zms = makeZmdAutoPortamentSwitch(zms, trkdata, target);
break;
/* [aftertouch.level] */
/* [aftertouch.delay] */
/* [aftertouch.switch] */
/* [aftertouch.sync] */
/* [vibrato.delth] */
/* : */
case ZMSCMD_ARCC: /* [arcc..] */
zms = makeARCCCommand(zms,trkdata,target,trkinf);
break;
case ZMSCMD_VOLUME: /* [volume] */
zms = makeZmdVolume(zms, trkdata, target, trkinf, 0);
break;
case ZMSCMD_ATVOLUME: /* [@volume] */
zms = makeZmdVolume(zms, trkdata, target, trkinf, 1);
break;
case ZMSCMD_VELOCITY: /* [velocity] */
/*zms = setMMLatU(zms, trkdata, trkinf, target, 0);*/
zms = dispatchVelo(zms,trkdata,trkinf,cominf,target);
break;
case ZMSCMD_ATVELOCITY: /* [@velocity] */
zms = setMMLatU(zms, trkdata, trkinf, target, 1);
break;
#ifdef AAA
case ZMSCMD_VELOCITY_REVISE: /* [velocity.revise] */
for (trk = 0; target[trk] >= 0; trk++) {
zms = makeZmdRandVelo(zms + 6,trkdata,target[trk],
trkinf,cominf,line,linebuf);
}
zmserror("[velocity.revise] can use only for zmc2/zmc3.",line,linebuf,zms_,4,1);
break;
#endif
case ZMSCMD_PANPOT: /* [panpot] */
case ZMSCMD_ATPANPOT: /* [@panpot] */
{
int mode = (i == ZMSCMD_PANPOT)? 0 : 1;
zms = makeZmdPanpot(zms, trkdata, target, mode);
}
break;
case ZMSCMD_TEMPO: /* [tempo] */
case ZMSCMD_ATTEMPO: /* [@tempo] */
case ZMSCMD_TIMER: /* [timer] */
{
int mode;
if (i == ZMSCMD_TEMPO) {
mode = 0;
} else if (i == ZMSCMD_ATTEMPO) {
mode = 1;
} else {
mode = 2;
}
zms = makeZmdTempo(zms, trkdata, target, mode);
}
break;
case ZMSCMD_TIE_MODE: /* [tie_mode] */
zms = makeZmdTieMode(zms, trkdata, target);
break;
case ZMSCMD_TRACK_MODE: /* [track_mode] */
zms = makeZmdTrackMode(zms, trkdata, trkinf, target);
break;
case ZMSCMD_TRACK_DELAY: /* [track_delay] */
zms = makeZmdTrackDelay(zms, trkdata, target, trkinf, cominf, 1);
break;
case ZMSCMD_ALL_SOUND_OFF: /* [all_sound_off] */
makeZmdAllSoundOff(trkdata, target);
break;
case ZMSCMD_ECHO: /* [echo] */
zms = makeZmdEcho(zms, trkdata, trkinf, target,cominf);
break;
case ZMSCMD_KSIGN: /* [k.sign */
case ZMSCMD_KEY_SIGNATURE: /* [key_signature */
zms = makeZmdKsign(zms, target, trkinf);
break;
case ZMSCMD_KEY: /* [key] */
zms = makeZmdKey(zms, cominf, trkdata, target);
break;
case ZMSCMD_METER: /* [meter] */
zms = makeZmdMeter(zms, cominf, trkdata, target);
break;
case ZMSCMD_BAR: /* [bar] */
case ZMSCMD_BAR2: /* [measure] */
case ZMSCMD_BAR3: /* [-] */
zms = makeZmdBar(zms,trkdata,target);
break;
case ZMSCMD_REPLAY: /* [replay] */
zms = makeZmdReplay(zms, trkdata, target);
break;
case ZMSCMD_SYNCHRONIZE: /* [synchronize] */
zms = makeZmdSynchronize(zms, trkdata, target, cominf);
break;
case ZMSCMD_DUMMY: /* [dummy] */
makeZmdDummy(trkdata, target);
break;
case ZMSCMD_COMMENT: /* [comment] */
zms = makeZmdComment(zms, trkdata, target);
break;
case ZMSCMD_EVENT: /* [event] */
zms = makeZmdEvent(zms, trkdata, target);
break;
case ZMSCMD_CONTROL: /* [control] */
zms = makeZmdCChange(zms,trkdata,target);
break;
case ZMSCMD_NRPN: /* [nrpn] */
zms = makeZmdSetNRPN(zms, trkdata, target);
break;
case ZMSCMD_DAMPER: /* [damper] */
zms = makeZmdDamper(zms, trkdata, target, 1);
break;
case ZMSCMD_TRACK_FADER: /* [track_fader] */
zms = makeCHfader(zms,trkdata,target,trkinf,cominf,1);
break;
case ZMSCMD_CH_FADER: /* [ch_fader] */
zms = makeCHfader(zms,trkdata,target,trkinf,cominf,0);
break;
case ZMSCMD_EFFECT: /* [effect] */
zms = makeZmdEffect(zms,trkdata,target);
zms = skipSpc(zms);
break;
case ZMSCMD_EFFECT_REVERB: /* [effect.reverb] */
case ZMSCMD_EFFECT_CHORUS: /* [effect.chorus] */
case ZMSCMD_EFFECT_DELAY: /* [effect.delay] */
{
BYTE mode;
if (i == ZMSCMD_EFFECT_REVERB) {
mode = 0;
} else if (i == ZMSCMD_EFFECT_CHORUS) {
mode = 1;
} else if (i == ZMSCMD_EFFECT_DELAY) {
mode = 2;
}
zms = makeZmdEffect2(zms,trkdata,target,mode);
}
break;
case ZMSCMD_MIDI_DATA: /* [midi_data] */
zms = makeZmdExclusive(zms, trkdata, target, 0);
break;
case ZMSCMD_ROLAND_EXCLUSIVE: /* [roland_exclusive] */
zms = makeZmdExclusive(zms, trkdata, target, 0x41);
break;
case ZMSCMD_YAMAHA_EXCLUSIVE: /* [yamaha_exclusive] */
zms = makeZmdExclusive(zms, trkdata, target, 0x43);
break;
case ZMSCMD_INSTRUMENT_ID: /* [instrument_id] */
zms = makeZmdInstrumentId(zms,trkdata,target);
zms = skipSpc(zms);
break;
case ZMSCMD_GM_SYSTEM_ON: /* [gm_system_on] */
zms = makeZmdGmSystemOn(zms, trkdata, cominf, target);
break;
case ZMSCMD_GM2_SYSTEM_ON: /* [gm2_system_on] */
zms = makeZmdGm2SystemOn(zms, trkdata, cominf, target);
break;
case ZMSCMD_XG_SYSTEM_ON: /* [xg_system_on] */
zms = makeZmdXgSystemOn(zms, trkdata, cominf, target);
break;
case ZMSCMD_SC88_MODE_SET:
case ZMSCMD_SC88_MODE:
{
int trk;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
if (!trkinf[Trk].setdev) {
trkinf[Trk].setdev = 1;
*trkdata[Trk].zmd++ = 0xCA;
*trkdata[Trk].zmd++ = 0x41;
*trkdata[Trk].zmd++ = 0x10;
*trkdata[Trk].zmd++ = 0x42;
}
}
zms = makeZmdSc88ModeSet(zms, trkdata, target);
}
break;
case ZMSCMD_GATETIME_RESOLUTION: /* [gatetime_resolution] */
zms = makeZmdGatetimeResolution(zms,cominf,trkinf,target);
break;
default: /* [] ... pull portament */
zms = makePortament(zms,trkdata,target,trkinf,cominf,']');
for (trk = 0; target[trk] >= 0; trk++) {
trkinf[target[trk]].noteon = 1;
}
break;
}
if (*zms == ']') {
zms++;
}
return zms;
}
UBYTE *makeCHfader(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[],
TRKINF *trkinf, COMMONINF *cominf,
int trk_fader)
/* trk_fader: 0=ch_fader 1=trk_fader */
{
DWORD ch, chtype;
DWORD zmd, zmd2, diff;
int trk;
const BYTE parabytes[3] = {2,1,1};
zmd = trkdata[target[0]].zmd - trkdata[target[0]].zmdbuf;
if (!trk_fader) {
zms = getDevice(zms, &ch, &chtype,cominf, 1);
if (*zms == ',') {
zms++;
}
}
zms = makeZmdManyParas2(zms, trkdata, target, line, linebuf,
0xD6, 3, parabytes, 1, -1, 4, 1, 0,
/* com, maxparas, ,omit?,ARCCno, space, times, mustover0 */
"[CH_FADER]: too many parameters.",
"[CH_FADER] can't use relational parameters.",
NULL);
/* zmd2 = trkdata[target[0]].zmd - trkdata[target[0]].zmdbuf; */
/* diff = zmd2 - zmd; */
diff = zmd;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
UBYTE *obp = trkdata[Trk].zmdbuf + diff + 1;
if (!trk_fader) {
if (chtype == -2) {
chtype = -1;
}
putWord(obp, chtype);
if (ch == -2) {
ch = -1;
}
putWord(obp + 2, ch);
} else {
putWord(obp, 0x7ffe);
putWord(obp + 2, 0); /* current track */
}
}
zms = skipSpc(zms);
if (*zms == ']') {
zms++;
}
return zms;
}
UBYTE *makeZmdEffect(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[])
{
const BYTE parabytes[5] = {1,1,1,1,1};
return makeZmdManyParas2(zms,trkdata,target,line,linebuf,
0xF0, 5, parabytes, 1, -1, 0, 1, 0,
"@e: too many parameters.",
"@e can't use relational parameters.",
"");
}
/* MT-32 is not supported yet */
UBYTE *makeZmdEffect2(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[],
const BYTE mode)
{
int trk, i;
UBYTE flg = 1;
DWORD para;
for (i = 0; i < mode; i++) {
flg <<= 1;
}
zms = get1AbsPara(zms,¶,0,255,
"[EFFECT] parameter is out of range(0-255).",
"[EFFECT] must be followed to its parameter.");
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
*trkdata[Trk].zmd++ = 0xF0;
*trkdata[Trk].zmd++ = flg;
*trkdata[Trk].zmd++ = para;
}
return zms;
}
UBYTE *makeZmdInstrumentId(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[])
{
return makeZmdManyParas(zms,trkdata,target,line,linebuf,
0xCA, 0xFF, 3, 1, 0,
"@i must have 3 parameters(maker id,device id,model id).",
"@i can't omit 3 parameters(maker id,device id,model id).",
"@i can't use relational parameters.");
}
UBYTE *makeZmdSynchronize(UBYTE *zms_,TRKCHINF *trkdata, const BYTE target[],
COMMONINF *cominf)
{
UBYTE *zms;
int trk, err;
DWORD tmpDWORD;
zms = getnum2(zms_, &tmpDWORD, &err);
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
if (err < 0) { /* W */
*trkdata[Trk].zmd++ = 0xFB;
} else {
int i, f = 0;
for (i = 0; i < cominf->maxtrk; i++) { /* Wn */
if (cominf->trkassign[i] == tmpDWORD) {
*trkdata[Trk].zmd++ = 0xBE;
putWord(trkdata[Trk].zmd, i); /* - 1; */
trkdata[Trk].zmd +=2;
f = 1;
break;
}
}
if (!f) {
zmserror("illegal track number.",line,linebuf,zms,0,1);
}
}
}
return zms;
}
UBYTE *makeZmdBar(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[])
{
while (1) {
if (*zms == 0x0D || *zms == 0x0A) {
zmserror("illegal track number.",line,linebuf,zms,0,1);
} else if (*zms == ']') {
int trk;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
*trkdata[Trk].zmd++ = 0xFE;
}
break;
}
}
return zms;
}
UBYTE *makeZmdTieMode(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[])
{
DWORD para;
int err, trk;
const char *p[] = {"normal","special","enhanced",NULL};
zms = getnum4(zms,¶,&err, p, -3);
if (err < 0) {
para = 0;
} else if (para == -3) {
para = 0;
} else if (para == -2 || para == -1) {
para = 1;
}
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
*trkdata[Trk].zmd++ = 0x9E;
*trkdata[Trk].zmd++ = para;
}
return zms;
}
UBYTE *makeZmdTrackMode(UBYTE *zms, TRKCHINF *trkdata, TRKINF *trkinf,
const BYTE target[])
{
DWORD para;
int err, trk;
const char *p[] = {"normal","rhythm",NULL};
zms = getnum4(zms,¶,&err, p, -2);
if (err < 0 || para == -2) {
para = 0;
} else {
para = 0x80;
}
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
*trkdata[Trk].zmd++ = 0xA4;
*trkdata[Trk].zmd++ = para;
if (trkinf[Trk].noteon) {
trkdata[Trk].trkm = (para)? 1 : 0;
}
}
return zms;
}
UBYTE *makeZmdTrackDelay(UBYTE *zms_, TRKCHINF *trkdata, const BYTE target[],
TRKINF *trkinf, COMMONINF *cominf, int mode)
{
int trk;
UBYTE *zms;
DWORD line_ = line;
LINEDATA *ld_ = ld;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
UWORD step;
int err;
line = line_;
ld = ld_;
if (!mode) {
zms = getStep(zms_, &step, trkinf[Trk].Step, &err,cominf);
} else {
DWORD s;
zms = getnum2(zms_, &s, &err);
step = s;
}
*trkdata[Trk].zmd++ = 0x81;
trkdata[Trk].zmd += putZvar(trkdata[Trk].zmd, step);
zms = skipSpcCr(zms);
if (*zms == '&') { /* @w with TIE */
zmserror("@w can't use with TIE on V3.",line,linebuf,zms,0,1);
}
incrementStepCounters(&trkinf[Trk], step);
}
return zms;
}
void makeZmdAllSoundOff(TRKCHINF *trkdata, const BYTE target[])
{
int trk;
for (trk = 0; target[trk] >= 0; trk++) {
*trkdata[target[trk]].zmd++ = 0xFD;
}
}
UBYTE *makeZmdEcho(UBYTE *zms, TRKCHINF *trkdata, TRKINF *trkinf,
const BYTE target[], COMMONINF *cominf)
{
DWORD para;
int err, trk;
UWORD itv;
UBYTE *zms_ = zms;
const char *p[] = {"loop",NULL};
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
zms = getStep(zms_, &itv, trkinf[Trk].Step,&err,cominf);
if (itv <= 0) {
zmserror("ECHO's 1st parameter must be over 0.",line,linebuf,zms,0,1);
}
trkinf[Trk].echoitv = itv;
if (*zms == ',') {
zms++;
}
zms = skipSpc(zms);
if (*zms == ']') {
break;
}
zms = getnum2(zms, ¶,&err);
if (err > 0) {
zmserror("ECHO's 2nd parameter error.",line,linebuf,zms,0,1);
}
trkinf[Trk].echodec = para;
if (*zms == ',') {
zms++;
}
zms = skipSpc(zms);
if (*zms == ']') {
break;
}
zms = getnum4(zms,¶,&err, p, 0);
if (err > 0 || para < 0) {
zmserror("ECHO's 3rd parameter error.",line,linebuf,zms,0,1);
}
trkinf[Trk].echolp = para;
}
return zms;
}
UBYTE *makeZmdDamper(UBYTE *zms, TRKCHINF *trkdata,
const BYTE target[], int mode)
{
DWORD para;
int err, trk;
const char *p[] = {"off","on",NULL};
zms = getnum4(zms,¶,&err, p, -2);
if (err < 0 || para == -2) {
para = 0;
} else if (para == -1) {
para = 127;
}
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
*trkdata[Trk].zmd++ = 0xA3;
if (mode) {
*trkdata[Trk].zmd++ = para;
} else {
*trkdata[Trk].zmd++ = (para)? 127 : 0;
}
}
return zms;
}
UBYTE *makeZmdBendRange(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[])
{
DWORD para;
int err, trk;
zms = getnum2(zms,¶,&err);
if (err < 0) {
zmserror("@g can't omit its parameter.",line,linebuf,zms,0,1);
}
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
*trkdata[Trk].zmd++ = 0xA5;
*trkdata[Trk].zmd++ = para;
}
return zms;
}
UBYTE *makeZmdProgramChange(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[])
{
int trk, err, cmd = 0;
DWORD tone, b1, b2 = 0;
zms = getnum2(zms,&tone,&err);
if (!err) {
zms = skipSpc(zms);
if (*zms == ':' && *(zms + 1) != '|') { /* @n1:n2,n3 */
cmd = 1;
b1 = tone;
zms = getnum2(zms + 1, &b2, &err);
if (err) {
b2 = 0xFF;
}
zms = skipSpc(zms);
if (*zms == ',') {
zms = getnum2(zms + 1, &tone, &err);
if (err) {
zmserror("`@'(program set) error.",line,linebuf,zms,0,1);
}
} else {
zmserror("`@'(program set) error.",line,linebuf,zms,0,1);
}
} else if (*zms == ',') { /* @n1,n2 */
cmd = 2;
b1 = (tone >> 7) & 0x7F;
b2 = tone & 0x7F;
zms = getnum2(zms + 1, &tone, &err);
if (err) {
zmserror("`@'(program set) error.",line,linebuf,zms,0,1);
}
}
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
if (cmd) {
*trkdata[Trk].zmd++ = 0xC6;
*trkdata[Trk].zmd++ = b1;
*trkdata[Trk].zmd++ = b2;
}
*trkdata[Trk].zmd++ = 0xC7;
putWord(trkdata[Trk].zmd, tone - 1);
trkdata[Trk].zmd += 2;
}
} else {
zmserror("`@'(program set) must be followed to its parameter.",line,linebuf,zms,0,1);
}
return zms;
}
UBYTE *makeZmdProgramBankChange(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[])
{
return makeZmdManyParas(zms,trkdata,target,line,linebuf,
0xC6, 0x00, 2, 1, 1,
"i: too many parameters.",
"i: can't use relational parameters.",
"");
}
UBYTE *makeZmdSetNRPN(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[])
{
int trk;
const DWORD line_ = line;
LINEDATA *ld_ = ld;
UBYTE *zms_ = zms;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
UWORD bytes = 0;
line = line_;
ld = ld_;
zms = zms_ - 1;
*trkdata[Trk].zmd++ = 0xCF;
do {
int err;
DWORD tmpDWORD;
zms = getnum2(++zms,&tmpDWORD,&err);
if (err >= 0) {
if (tmpDWORD >= 0x80) {
*trkdata[Trk].zmd++ = tmpDWORD & 0x7F;
*trkdata[Trk].zmd++ = tmpDWORD >> 7;
bytes += 2;
} else {
*trkdata[Trk].zmd++ = tmpDWORD;
bytes++;
}
zms = skipSpcCr(zms);
} else {
break;
}
} while(*zms == ',');
if (bytes < 3) {
zmserror("NRPN must have address(2 bytes) and data(1 or 2 bytes.)",line,linebuf,zms,0,1);
} else {
int i;
for (i = bytes; i < 4; i++) {
*trkdata[Trk].zmd++ = 0xFF;
}
}
}
return zms;
}
/*tenuki*/
UBYTE *makeZmdCChange(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[])
{
int trk;
DWORD tmpDWORD;
UBYTE *zms_ = zms;
const DWORD line_ = line;
LINEDATA *ld_ = ld;
for (trk = 0; target[trk] >= 0; trk++) {
int i;
/* (BEGIN FM/ADPCMsupport by Mamiya */
if (checkInternalDevice(trkdata,target[trk])) {
int err ;
DWORD reg, dat ;
line = line_;
ld = ld_;
zms = getnum2(zms_, ®, &err) ;
if (err < 0) {
zmserror("control change must have 2 parameters.",line,linebuf,zms,0,1);
continue;
}
zms = skipSpcCr(zms);
if (*zms != ',') {
zmserror("control change must have 2 parameters.",line,linebuf,zms,0,1);
continue;
}
zms = getnum2(zms + 1, &dat, &err) ;
if (err < 0) {
zmserror("control change must have 2 parameters.",line,linebuf,zms,0,1);
continue;
}
if (reg < 0x38 && reg == 0x30 + trkdata[target[trk]].ch) {
*trkdata[target[trk]].zmd++ = 0xD1;
dat >>= 2;
putWord(trkdata[target[trk]].zmd, dat);
dat *= 683;
dat >>= 6;
putWord(trkdata[target[trk]].zmd + 2, dat);
trkdata[target[trk]].zmd += 4;
continue;
}
switch (reg) {
case 2:
dat &= 511 ;
*trkdata[target[trk]].zmd++ = 0x9B;
putWord(trkdata[target[trk]].zmd, dat);
trkdata[target[trk]].zmd += 2 ;
break ;
case 3:
*trkdata[target[trk]].zmd++ = 0xB7;
*trkdata[target[trk]].zmd++ = dat & 3;
break ;
case 13:
*trkdata[target[trk]].zmd++ = 0xA2;
*trkdata[target[trk]].zmd++ = dat & 7;
break ;
case 14:
*trkdata[target[trk]].zmd++ = 0xB8;
*trkdata[target[trk]].zmd++ = dat & 1;
break ;
case 15:
if (dat == 0) {
*trkdata[target[trk]].zmd++ = 0x82;
} else {
*trkdata[target[trk]].zmd++ = 0xA5;
*trkdata[target[trk]].zmd++ = dat;
}
break ;
default:
*trkdata[target[trk]].zmd++ = 0xBC;
*trkdata[target[trk]].zmd++ = reg;
*trkdata[target[trk]].zmd++ = dat;
break ;
}
continue ;
}
/* FM/ADPCMsupport by Mamiya END) */
*trkdata[target[trk]].zmd++ = 0xBC;
zms = zms_ - 1;
line = line_;
ld = ld_;
for (i = 0; i < 2; i++) {
zms = get1AbsPara(++zms,&tmpDWORD,0,127,
"control change parameter is out of range(0-127).",
"'y'(control change) must be followed to its parameter.");
*trkdata[target[trk]].zmd++ = tmpDWORD;
zms = skipSpcCr(zms);
if (i != 2 - 1 && *zms != ',') {
zmserror("control change must have 2 parameters.",line,linebuf,zms,0,1);
}
}
}
return zms;
}
UBYTE *makeZmdKsign(UBYTE *zms, const BYTE target[],TRKINF *trkinf)
{
int trk;
UBYTE *zms_ = zms;
const DWORD line_ = line;
LINEDATA *ld_ = ld;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
int i,kp = 0,kpflg = 0;
int var[2] = { 0, 0 };
const BYTE tonetbl[7] = { 0, 2, 4, 5, 7, 9, 11 };
zms = skipSpcCr(zms_);
line = line_;
ld = ld_;
for (i = 0; i < 12; i++) {
trkinf[Trk].ksign[i] = 0;
}
if (*zms != '#' && *zms != '+' && *zms != '-') {
zms = makeZmdKey0(zms, var);
if (var[1] >= 0) {
const char *cho="fcgdaeb";
/* fprintf(stderr,"[%d %d] ",var[0], var[1]);*/
if (var[0] > 0) {
int i;
for (i = 0; i < var[0]; i++) {
int note = cho[i] - 'a' - 2;
if (note < 0) {
note += 7;
}
trkinf[Trk].ksign[tonetbl[note]] = 1;
}
} else if (var[0] < 0) {
int i;
for (i = 7; i > 7+var[0]; i--) {
int note = cho[i] - 'a' - 2;
if (note < 0) {
note += 7;
}
trkinf[Trk].ksign[tonetbl[note]] = -1;
}
}
zms = skipSpc(zms);
}
}
while (*zms != ']') {
int note;
zms = skipSpcCr(zms);
switch(*zms++) {
case '#':
case '+':
if (kpflg) {
kp = 1;
kpflg = 0;
} else {
kp++;
}
break;
case '-':
if (kpflg) {
kp = -1;
kpflg = 0;
} else {
kp--;
}
break;
case 'a': case 'A': case 'b': case 'B':
case 'c': case 'C': case 'd': case 'D':
case 'e': case 'E': case 'f': case 'F':
case 'g': case 'G':
kpflg = 1;
note = (*(zms - 1) | 0x20) - 'a';
note -= 2;
if (note < 0) {
note += 7;
}
trkinf[Trk].ksign[tonetbl[note]] = kp;
break;
case ',':
break;
default:
zmserror("ksign error.",line,linebuf,zms,0,1);
break;
}
zms = skipSpcCr(zms);
}
}
return zms;
}
/*tenuki*/
UBYTE *makeZmdReplay(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[])
{
int trk, err;
DWORD para;
zms = getnum2(zms, ¶, &err);
if (!err) {
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
*trkdata[Trk].zmd++ = 0xbd;
putWord(trkdata[Trk].zmd, para);
trkdata[Trk].zmd += 2;
}
} else {
zmserror("J/[REPLAY] requires the target track parameter.",line,linebuf,zms,0,1);
}
return zms;
}
void makeZmdDummy(TRKCHINF *trkdata, const BYTE target[])
{
int trk;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
*trkdata[Trk].zmd++ = 0xfa;
}
}
UBYTE *makeZmdComment(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[])
{
int trk;
UBYTE *zms_;
DWORD len;
zms_ = zms = skipSpc(zms);
while (*zms != ']' && *zms != 0x0d && *zms != 0x0a) {
zms++;
}
if (*zms == 0x0d || *zms == 0x0a) {
zmserror("[comment] format error.",line,linebuf,zms,0,1);
}
len = zms - zms_;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
int i;
*trkdata[Trk].zmd++ = 0xd2;
*trkdata[Trk].zmd++ = 0;
putDword(trkdata[Trk].zmd, len);
trkdata[Trk].zmd += 4;
for (i = 0; i < len; i++) {
*trkdata[Trk].zmd++ = *zms_++;
}
}
return zms;
}
UBYTE *makeZmdEvent(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[])
{
const char *category[] = {"word", "picture","sound",NULL};
const char *cls0[] = {"string",NULL};
const char *cls1[] = {"pic",NULL};
const char *cls2[] = {"adpcm",NULL};
char **class_[3]; /* = {cls0,cls1,cls2} */ /* BCB can't do so */
int trk,err;
UBYTE *zms_, *obp;
DWORD len,cat,cls;
class_[0] = (char**)cls0;
class_[1] = (char**)cls1;
class_[2] = (char**)cls2;
zms = getnum4(zms,&cat,&err, category, 0);
if (err) {
zmserror("SYNTAX ERROR",line,linebuf,zms,0,1);
} else if (cat < 0 && 2 < cat) {
zmserror("EVENT category is not defined.",line,linebuf,zms,0,1);
}
if (cat > 0) {
zmserror("EVENT PICTURE/SOUND is not supported in z2m3.",line,linebuf,zms,4,1);
}
zms = skipSpc(zms);
if (*zms == ',') {
zms++;
}
zms = getnum4(zms,&cls,&err, (const char**)class_[cat], 0);
if (err) {
zmserror("SYNTAX ERROR",line,linebuf,zms,0,1);
} else if (cls < 0 && 2 < cls) {
zmserror("EVENT class is not defined.",line,linebuf,zms,0,1);
}
zms = skipSpc(zms);
if (*zms == ',') {
zms++;
}
zms = skipSpc(zms);
if (*zms == '\"') {
zms++;
}
zms_ = zms;
while (*zms != ']' && *zms != '\"' && *zms != 0x0d && *zms != 0x0a) {
zms++;
}
if (*zms == 0x0d || *zms == 0x0a) {
zmserror("[event] format error.",line,linebuf,zms,0,1);
}
len = zms - zms_;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
int i;
*trkdata[Trk].zmd++ = 0xf8;
putDword(trkdata[Trk].zmd, 1 + 1 + 2 + len + 1);
trkdata[Trk].zmd += 4;
*trkdata[Trk].zmd++ = cat;
*trkdata[Trk].zmd++ = cls;
*trkdata[Trk].zmd++ = 0;
*trkdata[Trk].zmd++ = 0;
for (i = 0; i < len; i++) {
*trkdata[Trk].zmd++ = *zms_++;
}
*trkdata[Trk].zmd++ = '\0';
}
if (*zms == '\"') {
zms++;
}
if (*zms == ']') {
zms++;
}
return zms;
}
UBYTE *makeZmdPanpot(UBYTE *zms, TRKCHINF *trkdata, const BYTE target[], int mode)
{ /* mode=-1: P mode=0: @P mode=1: [@PANPOT] */
int trk;
const DWORD line_ = line;
LINEDATA *ld_ = ld;
UBYTE *zms_ = zms;
UBYTE *linebuf_ = linebuf;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
const int tbl[] = {128, 0, 127, 64};
BYTE rel = 0;
DWORD vol; /* ,v = trkinf[Trk].vol; */
int err;
line = line_;
ld = ld_;
zms = skipSpcCr(zms_);
if (*zms == '+') {
rel = 1;
} else if (*zms == '-') {
rel = -1;
}
zms = getnum2(zms, &vol, &err);
if (mode < 0) {
if (rel) {
zmserror("P (panpot) must be followed to its absolute parameter.",line_,linebuf_,zms_,0,1);
} else {
vol = tbl[vol]; /* tenuki */
}
}
if (err < 0) { /* only '@p' */
zmserror("@p must be followed to its parameter.",line_,linebuf_,zms_,0,1);
} else {
if (rel || mode > 0) {
*trkdata[Trk].zmd++ = 0xA1;
*trkdata[Trk].zmd++ = vol;
} else {
if (vol < 0 || vol > 127) {
zmserror("panpot parameter is out of range(0-127).",line_,linebuf_,zms_,0,1);
} else {
*trkdata[Trk].zmd++ = 0xA0;
*trkdata[Trk].zmd++ = vol;
}
}
/* trkinf[Trk].vol = v; */
}
}
return zms;
}
UBYTE *makeZmdTempo(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[], int mode)
{ /* [TEMPO] mode=0: absolute mode=1: relative */
/* [TIMER] mode=2: absolute mode=3: relative */
UBYTE *zms_ = zms;
int trk;
char *linebuf_ = linebuf;
DWORD line_ = line;
LINEDATA *ld_ = ld;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
int err, rel = 0;
DWORD vol;
line = line_;
ld = ld_;
zms = skipSpcCr(zms_);
if (*zms == '+') {
rel = 1;
} else if (*zms == '-') {
rel = -1;
}
zms = getnum2(zms, &vol, &err);
if (err < 0) { /* only '@v' */
zmserror("tempo must be followed to its parameter.",line_,linebuf_,zms_,0,1);
} else {
if (rel || (mode & 1)) {
*trkdata[Trk].zmd++ = (mode & 2)? 0xC2 : 0xC4;
putWord(trkdata[Trk].zmd, vol);
trkdata[Trk].zmd += 2;
} else {
if (!(mode & 2) && (vol < 20 || 300 < vol)) {
zmserror("tempo parameter is out of range(20 - 300).",line_,linebuf_,zms_,0,1);
} else {
*trkdata[Trk].zmd++ = (mode & 2)? 0xC1 : 0xC3;
putWord(trkdata[Trk].zmd, vol);
trkdata[Trk].zmd += 2;
}
}
}
}
return zms;
}
UBYTE *makeZmdVolume(UBYTE *zms,TRKCHINF *trkdata, const BYTE target[],
TRKINF *trkinf, int mode)
{ /* mode=0:V mode=1:@V mode=-1:[@VOLUME] */
UBYTE *zms_ = zms;
DWORD line_ = line;
UBYTE *linebuf_ = linebuf;
LINEDATA *ld_ = ld;
int trk;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
BYTE rel = 0;
DWORD vol; /* ,v = trkinf[target[trk]].vol; */
int err;
line = line_;
ld = ld_;
zms = skipSpcCr(zms_);
if (*zms == '+') {
rel = 1;
} else if (*zms == '-') {
rel = -1;
}
zms = getnum2(zms, &vol, &err);
if (err < 0) { /* only '@v' */
zmserror("v/@v must be followed to its parameter.",line_,linebuf_,zms_,0,1);
} else {
if (rel || mode > 0) {
/* WARNING: v+ || v- will be fail */
*trkdata[Trk].zmd++ = 0x91;
*trkdata[Trk].zmd++ = vol;
/* (BEGIN FM/ADPCMsupport by Mamiya */
if (checkInternalDevice(trkdata,Trk) & 1) {
DWORD v = trkinf[Trk].velou.var[0];
v += vol ;
v = (v < 0) ? 0 : ((v > 127) ? 127 : v) ;
trkinf[Trk].velou.var[0] = v ;
}
/* FM/ADPCMsupport by Mamiya END) */
/* zmserror("@v is used relatively.",line_,linebuf_,zms_,4,1); */
} else {
if ( (!mode && (vol < 0 || vol > 127)) ||
( (mode < 0) && (vol < 0 || vol > 16)) ) {
zmserror("v/@v parameter is out of range.",line_,linebuf_,zms_,0,1);
} else {
*trkdata[Trk].zmd++ = 0x90;
*trkdata[Trk].zmd++ = (mode < 0)? 0x80 + vol : vol;
/* (BEGIN FM/ADPCMsupport by Mamiya */
if (checkInternalDevice(trkdata,Trk) & 1) {
trkinf[Trk].velou.var[0] = vol ;
}
/* FM/ADPCMsupport by Mamiya END) */
}
}
trkinf[Trk].volmode = (mode < 0)? 1 : 0;
/* trkinf[Trk].vol = v; */
}
}
return zms;
}
UBYTE *makeZmdExclusive(UBYTE *zms,TRKCHINF *trkdata,
const BYTE target[], const UBYTE id)
{
int trk;
DWORD line_ = line;
UBYTE *zms_ = zms;
LINEDATA *ld_ = ld;
for (trk = 0; target[trk] >= 0; trk++) {
UBYTE *zmd_;
const int Trk = target[trk];
line = line_;
ld = ld_;
zms = zms_ - 1;
if (id) {
*trkdata[Trk].zmd++ = 0xF3;
*trkdata[Trk].zmd++ = id;
} else {
*trkdata[Trk].zmd++ = 0xF4;
}
*trkdata[Trk].zmd++ = 0x00; /* comment length */
zmd_ = trkdata[Trk].zmd;
trkdata[Trk].zmd += 4;
do {
DWORD zmsbyte = 0;
trkdata[Trk].zmd = txt2bin(trkdata[Trk].zmd, ++zms, &zmsbyte);
zms += zmsbyte;
if (!zmsbyte) {
break;
}
} while(*zms == ',' || isspace(*zms));
putDword(zmd_, trkdata[Trk].zmd - zmd_ - 4);
}
return zms;
}
void makeZmdPitch(TRKCHINF *trkdata, int Trk, int st, DWORD var)
{
UBYTE code;
switch (st) {
case 0:
code = 0xB9;
break;
case 1:
code = 0xB8;
break;
case 2:
code = 0xBB;
break;
case 3:
code = 0xBA;
break;
}
*trkdata[Trk].zmd++ = code;
putWord(trkdata[Trk].zmd, var);
trkdata[Trk].zmd += 2;
}
UBYTE *makeZmdBend(UBYTE *zms, TRKCHINF *trkdata, TRKINF *trkinf, const BYTE target[], int st)
{
int trk;
DWORD line_ = line;
LINEDATA *ld_ = ld;
UBYTE *linebuf_ = linebuf;
UBYTE *zms_ = zms;
for (trk = 0; target[trk] >= 0; trk++) {
/*
const UBYTE mml = *(zms_ - 1);
const int st = (mml == 'b' || mml == 'B')? 1 : 0;
*/
const int Trk = target[trk];
DWORD tmpDWORD;
int err;
line = line_;
ld = ld_;
zms = getnum2(zms_, &tmpDWORD, &err);
zms = skipSpc(zms);
if (err < 0 && *zms !=',') { /* autobend sw off */
/*OK*/ *trkdata[Trk].zmd++ = 0x98;
*trkdata[Trk].zmd++ = 0x00;
} else {
/*OK*/ if (*zms == ',') { /* @bnnn,NNN */
DWORD tmpDWORD2, delay;
int errs[4] = {-2,-2,-2,-2};
DWORD p[4] = {0,0,0,0};
int i;
UBYTE of = (err != -1)? 1 : 0;
errs[0] = err;
p[0] = tmpDWORD;
for (i = 1; i < 4; i++) {
of <<= 1;
zms = getnum2(++zms, &p[i], &errs[i]);
zms = skipSpc(zms);
if (errs[i] > 0) {
zmserror("@b/@k can't omit delay parameter when you want to set.",line_,linebuf_,zms_,0,1);
} else if (errs[i] != -1) {
of++;
if (i == 2) {
trkinf[Trk].abdelay = p[2];
}
}
if (*zms != ',') {
int j;
for (j = i + 1; j < 8; j++) {
of <<= 1;
}
break;
}
}
*trkdata[Trk].zmd++ = (st)? 0xE0 : 0xE1;
*trkdata[Trk].zmd++ = of;
for (i = 0; i < 4; i++) {
if (errs[i] >= 0) {
putWord(trkdata[Trk].zmd, p[i]);
trkdata[Trk].zmd += 2;
}
}
} else { /* @bnnn */
/*OK*/ makeZmdPitch(trkdata, Trk, st, tmpDWORD);
}
}
}
return zms;
}
UBYTE *makeZmdProgramSplit(UBYTE *zms, TRKCHINF *trkdata, TRKINF *trkinf, const BYTE target[])
{
int trk;
DWORD line_ = line;
UBYTE *linebuf_ = linebuf;
UBYTE *zms_ = zms;
LINEDATA *ld_ = ld;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
const int octbak = trkinf[Trk].octave;
const char *p[] = {"off","on",NULL};
DWORD sw = 1;
int paras = 0, err;
UBYTE *zmd_;
linebuf = linebuf_;
line = line_;
ld = ld_;
*trkdata[Trk].zmd++ = 0xDE;
zmd_ = trkdata[Trk].zmd;
trkdata[Trk].zmd++;
zms = getnum4(zms_,&sw,&err, p, 0);
if (err || sw) {
sw = 0x80;
}
zms = skipSpcCr(zms);
if (*zms == ',') {
zms++;
}
if (*zms != ']') {
while (1) {
int err;
DWORD b1, b2 = 0, t1;
BYTE m1, n1;
linebuf = linebuf_;
line = line;
ld = ld_;
zms = getnum2(zms, &b1, &err);
if (err) {
zmserror("[timbre_split] parameter error.",line,linebuf,zms,0,1);
}
zms = skipSpcCr(zms);
if (*zms == ':') {
zms = getnum2(zms + 1, &b2, &err);
if (err) {
zmserror("[timbre_split] parameter error.",line,linebuf,zms,0,1);
}
b1 <<= 7;
b1 += b2;
}
if (*zms == ',') {
zms++;
}
zms = getnum2(zms, &t1, &err);
if (*zms == ',') {
zms++;
}
zms = getZmsNoteSub(zms, trkinf ,Trk, &m1);
if (*zms == ',') {
zms++;
}
zms = getZmsNoteSub(zms, trkinf, Trk, &n1);
*trkdata[Trk].zmd++ = m1;
*trkdata[Trk].zmd++ = n1;
putWord(trkdata[Trk].zmd, b1);
trkdata[Trk].zmd += 2;
putWord(trkdata[Trk].zmd, t1 - 1);
trkdata[Trk].zmd += 2;
paras++;
zms = skipSpcCr(zms);
if (*zms != ',') {
break;
} else {
zms++;
}
}
}
*zmd_ = sw + paras;
trkinf[Trk].octave = octbak;
}
return zms;
}
UBYTE *getZmsNoteSub(UBYTE *zms, TRKINF *trkinf, const int Trk, BYTE *note)
{
*note = (trkinf[Trk].octave + 1) * 12;
while (1) {
if (*zms == 'o' || *zms == 'O') {
zms = checkOctaveChange(zms, trkinf, Trk);
*note = (trkinf[Trk].octave + 1) * 12;
} else if (*zms == '<') {
*note += 12;
trkinf[Trk].octave++;
zms++;
} else if (*zms == '>') {
*note -= 12;
trkinf[Trk].octave--;
zms++;
} else if ('a' <= tolower(*zms) && tolower(*zms) <= 'g') {
const BYTE tonetbl[7] = { 0, 2, 4, 5, 7, 9, 11 };
BYTE n = tolower(*zms) - 'a' - 2;
if (n < 0) {
n += 7;
}
*note += tonetbl[n];
zms++;
} else if (*zms == '#' || *zms == '+') {
note++;
zms++;
} else if (*zms == '-') {
note--;
zms++;
} else if (isspace(*zms)) {
zms++;
} else if (isdigit(*zms)) {
DWORD tmp;
int err;
zms = getnum2(zms, &tmp, &err);
*note = tmp;
} else {
break;
}
}
return zms;
}